package com.atguigu.yygh.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.common.exception.YyghException;
import com.atguigu.yygh.enums.OrderStatusEnum;
import com.atguigu.yygh.enums.PaymentStatusEnum;
import com.atguigu.yygh.enums.PaymentTypeEnum;
import com.atguigu.yygh.enums.RefundStatusEnum;
import com.atguigu.yygh.model.order.OrderInfo;
import com.atguigu.yygh.model.order.PaymentInfo;
import com.atguigu.yygh.model.order.RefundInfo;
import com.atguigu.yygh.order.prop.WeiPayProperties;
import com.atguigu.yygh.order.service.OrderInfoService;
import com.atguigu.yygh.order.service.PaymentService;
import com.atguigu.yygh.order.service.RefundInfoService;
import com.atguigu.yygh.order.service.WeixinService;
import com.atguigu.yygh.order.utils.ConstantPropertiesUtils;
import com.atguigu.yygh.order.utils.HttpClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.lang.model.element.VariableElement;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class WeixinServiceImpl implements WeixinService {

    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private WeiPayProperties weiPayProperties;

    @Autowired
    private RefundInfoService refundInfoService;
    @Override
    public String createNative(Long orderId) {
        //1、根据订单id去数据库获取订单信息
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        //2、保存支付记录
        paymentService.savePaymentInfo(orderInfo, PaymentTypeEnum.WEIXIN.getStatus());
        //3、请求微信服务器，获取微信支付地址
        HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
        HashMap<String, String> map = new HashMap<>();
        map.put("appid", ConstantPropertiesUtils.APPID);
        map.put("mch_id", ConstantPropertiesUtils.PARTNER);
        map.put("nonce_str", WXPayUtil.generateNonceStr());
        Date reserveDate = orderInfo.getReserveDate();
        String reserveDateString = new DateTime(reserveDate).toString("yyyy/MM/dd");
        String body = reserveDateString + "就诊"+ orderInfo.getDepname();
        map.put("body", body);
        map.put("out_trade_no", orderInfo.getOutTradeNo());
        //map.put("total_fee", order.getAmount().multiply(new BigDecimal("100")).longValue()+"");
        map.put("total_fee", "1");//为了测试
        map.put("spbill_create_ip", "127.0.0.1");
        map.put("notify_url", "http://guli.shop/api/order/weixinPay/weixinNotify");
        map.put("trade_type", "NATIVE");
        try {
            httpClient.setXmlParam(WXPayUtil.generateSignedXml(map, weiPayProperties.getPartnerkey()));
            httpClient.setHttps(true);
            httpClient.post();
            String s = httpClient.getContent();
            Map<String, String> xmlToMap = WXPayUtil.xmlToMap(s);
            System.out.println("map = " + xmlToMap);
            return xmlToMap.get("code_url");
        } catch (Exception e) {
            throw new YyghException(20001, "微信支付失败！");
        }
    }

    @Override
    public Map<String, String> queryPayStatus(Long orderId) {
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        Map paramMap = new HashMap<>();
        paramMap.put("appid", ConstantPropertiesUtils.APPID);
        paramMap.put("mch_id", ConstantPropertiesUtils.PARTNER);
        paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
        paramMap.put("nonce_str", WXPayUtil.generateNonceStr());
        //2、设置请求
        HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
        try {
            client.setXmlParam(WXPayUtil.generateSignedXml(paramMap, weiPayProperties.getPartnerkey()));
            client.setHttps(true);
            client.post();
            String content = client.getContent();
            Map<String, String> xmlToMap = WXPayUtil.xmlToMap(content);
            return xmlToMap;
        } catch (Exception e) {
            return null;
        }
    }

    @Transactional
    @Override
    public void paySuccess(Long orderId, Map<String, String> resultMap) {
        //更改订单状态，处理支付结果
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(orderId);
        orderInfo.setOrderStatus(OrderStatusEnum.PAID.getStatus());
        orderInfoService.updateById(orderInfo);
        //更新支付记录表
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("order_id", orderId);
        updateWrapper.set("trade_no", resultMap.get("transaction_id"));  //微信服务器生成
        updateWrapper.set("callback_time", new Date());
        updateWrapper.set("callback_content", JSONObject.toJSONString(resultMap));
        updateWrapper.set("payment_status", PaymentStatusEnum.PAID.getStatus());
        paymentService.update(updateWrapper);
    }


    @Override
    public boolean refund(Long orderId) {
        QueryWrapper<PaymentInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("order_id", orderId);
        PaymentInfo paymentInfo = paymentService.getOne(wrapper);
        RefundInfo refundInfo = refundInfoService.saveRefundInfo(paymentInfo);
        if (refundInfo.getRefundStatus().intValue() == RefundStatusEnum.REFUND.getStatus().intValue()) {
            return true;
        }
        Map<String,String> paramMap = new HashMap<>(8);
        paramMap.put("appid",ConstantPropertiesUtils.APPID);       //公众账号ID
        paramMap.put("mch_id",ConstantPropertiesUtils.PARTNER);   //商户编号
        paramMap.put("nonce_str",WXPayUtil.generateNonceStr());
        paramMap.put("transaction_id",paymentInfo.getTradeNo()); //微信订单号
        paramMap.put("out_trade_no",paymentInfo.getOutTradeNo()); //商户订单编号
        paramMap.put("out_refund_no","tk"+paymentInfo.getOutTradeNo()); //商户退款单号
        //       paramMap.put("total_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
        //       paramMap.put("refund_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
        paramMap.put("total_fee","1");
        paramMap.put("refund_fee","1");
        try {
            String s = WXPayUtil.generateSignedXml(paramMap, weiPayProperties.getPartnerkey());
            HttpClient httpClient = new HttpClient("https://api.mch.weixin.qq.com/secapi/pay/refund");
            httpClient.setXmlParam(s);
            httpClient.setHttps(true);
            httpClient.setCert(true);
            httpClient.setCertPassword(weiPayProperties.getPartner());
            httpClient.post();

            String content = httpClient.getContent();
            Map<String, String> map = WXPayUtil.xmlToMap(content);
            if (map != null && WXPayConstants.SUCCESS.equalsIgnoreCase(map.get("result_code"))) {
                refundInfo.setCallbackTime(new Date());
                refundInfo.setTradeNo(map.get("refund_id"));
                refundInfo.setRefundStatus(RefundStatusEnum.REFUND.getStatus());
                refundInfo.setCallbackContent(JSONObject.toJSONString(map));
                refundInfoService.updateById(refundInfo);
                return true;
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}